﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Transactions;
using System.Web;
using FTBS.Models.Entities;

namespace FTBS.Models.DAO
{
    public class TicketDAO
    {
        private FilmTicketBookingSystemEntities _entity = new FilmTicketBookingSystemEntities();
        private ChairDAO _chairDao = new ChairDAO();

        /// <summary>
        /// check status of created ticket
        /// </summary>
        /// <param name="scheduleId"></param>
        /// <param name="chairId"></param>
        /// <returns>number of ticket</returns>
        /// <author>hungph</author>
        public int CheckCreatedTicket(int scheduleId, int chairId)
        {
            var count = _entity.Tickets.Count(ticket => ticket.ChairId == chairId && ticket.ScheduleId == scheduleId && ticket.IsDeleted == false);
            return count;
        }

        public int CheckTicketToCreate(int scheduleId, int chairId)
        {
            var count = _entity.Tickets.Count(ticket => ticket.ChairId == chairId && ticket.ScheduleId == scheduleId);
            return count;
        }

        public bool CheckTicket(int id)
        {
            var selectSchedule = from schedule in _entity.Schedules
                             where schedule.RoomId == id
                                   && schedule.IsCreateTicket == true
                                   && schedule.IsDeleted == false
                             select schedule;
            if (selectSchedule.Count() > 0)
            {
                return true;
            }
            return false;
            //var resultQuerry = _entity.Schedules.Any(s => s.Room.RoomId == id && s.IsCreateTicket == true && s.IsDeleted == false);
            //return resultQuerry;
        }

        public int CountTicketsByScheduleId(int scheduleId)
        {
            var count = _entity.Tickets.Count(ticket => ticket.ScheduleId == scheduleId && ticket.IsDeleted == false);
            return count;
        }

        public int CountBookedTicketsByScheduleId(int scheduleId)
        {
            var count = _entity.Tickets.Count(ticket => ticket.ScheduleId == scheduleId && ticket.IsDeleted == false && ticket.Status == true);
            return count;
        }

        public int GetTicketId(int scheduleId, int chairId)
        {
            int ticketId = 0;
            var tickets = from tk in _entity.Tickets where tk.ScheduleId == scheduleId && tk.ChairId == chairId select tk;
            Ticket ticket = tickets.FirstOrDefault();
            if (ticket != null)
            {
                ticketId = ticket.TicketId;
            }
            return ticketId;
        }

        public Ticket GetTicket(int scheduleId, int chairId)
        {
            var tickets = from tk in _entity.Tickets where tk.ScheduleId == scheduleId && tk.ChairId == chairId select tk;
            Ticket ticket = tickets.FirstOrDefault();
            return ticket;
        }

        public int AddTicket(Ticket ticket)
        {
            try
            {
                ticket.PurePrice = 0;
                ticket.Price = 0;
                ticket.Status = false;
                ticket.IsDeleted = true;
                ticket.TicketTypeId = 1;
                _entity.Tickets.Add(ticket);
                int resultQuery = _entity.SaveChanges();
                return resultQuery;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int AddTickets(List<Ticket> listOfTickets)
        {
            try
            {
                using (TransactionScope trans = new TransactionScope())
                {
                    try
                    {
                        foreach (var ticket in listOfTickets)
                        {
                            ticket.PurePrice = 0;
                            ticket.Price = 0;
                            ticket.Status = false;
                            ticket.IsDeleted = true;
                            ticket.TicketTypeId = 1;
                            _entity.Tickets.Add(ticket);
                        }
                        int result = _entity.SaveChanges();
                        trans.Complete();
                        return result;
                    }
                    catch (Exception)
                    {
                        trans.Dispose();
                        return 0;
                    }
                }
            }
            catch (Exception ex)
            {
                return 0;
                //throw ex;
            }
        }

        public Ticket GetTicketById(int ticketId)
        {
            Ticket ticket = new Ticket();
            ticket = (from ticketEnt in _entity.Tickets
                      where ticketEnt.TicketId == ticketId
                      select ticketEnt).FirstOrDefault();
            return ticket;
        }

        public int UpdateTicket(int ticketId, bool isDelete)
        {
            try
            {
                Ticket ticket = GetTicketById(ticketId);
                ticket.IsDeleted = isDelete;
                _entity.Entry(ticket).State = EntityState.Modified;
                int resultQuery = _entity.SaveChanges();
                return resultQuery;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int UpdatePriceTicket(int ticketId, double price, bool isDelete)
        {
            try
            {
                Ticket ticket = GetTicketById(ticketId);
                ticket.IsDeleted = isDelete;
                ticket.PurePrice = price;
                _entity.Entry(ticket).State = EntityState.Modified;
                int resultQuery = _entity.SaveChanges();
                return resultQuery;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<Ticket> getListTicket(int id)
        {
            List<Ticket> listChairId = new List<Ticket>();
            listChairId = _entity.Tickets.Where(s => s.ScheduleId == id).ToList();
            return listChairId;
        }

        /// <summary>
        /// check enough price ticket of theater to create ticket
        /// </summary>
        /// <param name="scheduleId"></param>
        /// <returns>true : can create ticket; false: can't create ticket</returns>
        /// <author>hungph</author>
        public bool CheckEnoughPriceTicketToCreateTicket(int scheduleId)
        {
            var theaterId = _entity.Schedules.Find(scheduleId).TheaterId;
            var numberExistedPriceTicketOfTheater =
                _entity.PriceTickets.Count(
                    pt => pt.IsDeleted == false && pt.TheaterId == theaterId);
            var numberChairTYpeOfTheater = _entity.ChairTypes.Count(ct => ct.IsDeleted == false);
            if (numberChairTYpeOfTheater == numberExistedPriceTicketOfTheater)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// check price ticket of theater must > 0 to create ticket
        /// </summary>
        /// <returns>true : can create ticket; false: can't create ticket</returns>
        /// <author>hungph</author>
        public bool CheckPriceToCreateTicket(int scheduleId)
        {
            var result = true;
            var listChairType = from ct in _entity.ChairTypes select ct;
            var priceTicket = new PriceTicket();
            if (listChairType != null)
            {
                foreach (var chairType in listChairType)
                {
                    try
                    {
                        var theaterId = _entity.Schedules.Find(scheduleId).TheaterId;
                        priceTicket = (from pt in _entity.PriceTickets
                                       where
                                           pt.TheaterId == theaterId && pt.IsDeleted == false
                                           && pt.ChairTypeId == chairType.ChairTypeId
                                       select pt).FirstOrDefault();
                        if (priceTicket != null)
                        {
                            if (Int64.Parse(priceTicket.Price.ToString().Trim()) >= 0)
                            {
                                result = true;
                            }
                            else
                            {
                                return false;
                            }
                        }

                    }
                    catch (Exception e)
                    {
                        return false;
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// Update PurePrice in Ticket when update Price in PriceTicket table
        /// </summary>
        /// <param name="priceTicket"></param>
        //public int UpdateTicketPurePrice(PriceTicket priceTicket)
        //{
        //    try
        //    {
        //        var theaterId = priceTicket.TheaterId;
        //        var scheduleId = (from schedule in _entity.Schedules
        //                         where schedule.IsDeleted == false
        //                               && schedule.IsCreateTicket == true
        //                               && schedule.TheaterId == theaterId
        //                         select schedule.ScheduleId).FirstOrDefault();
        //        var listTicket = from ticket in _entity.Tickets
        //                         where ticket.ScheduleId == scheduleId
        //                               && ticket.Status == false
        //                         select ticket;
        //        foreach (var ticket in listTicket)
        //        {
        //            Ticket t = _entity.Tickets.Find(ticket.TicketId);
        //            t.PurePrice = priceTicket.Price;
        //            _entity.Entry(t).State = EntityState.Modified;
        //        }
        //        int result = _entity.SaveChanges();
        //        return result;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //        return 0;
        //    }
        //}

        /// <summary>
        /// update price for ticket when edit price ticket of theater
        /// </summary>
        /// <param name="priceTicket"></param>
        /// <returns></returns>
        public void UpdateTicketPurePrice(PriceTicket priceTicket)
        {
            try
            {
                var theaterId = priceTicket.TheaterId;
                var chairTypeId = priceTicket.ChairTypeId;
                var listTicket = from ticket in _entity.Tickets
                                 join schedule in _entity.Schedules on ticket.ScheduleId equals schedule.ScheduleId
                                 join chair in _entity.Chairs on ticket.ChairId equals chair.ChairId
                                 where schedule.TheaterId == theaterId && schedule.IsDeleted == false && schedule.IsCreateTicket == true && ticket.Status == false && chair.ChairTypeId == chairTypeId && ticket.IsDeleted == false
                                 select ticket;

                foreach (var ticket in listTicket)
                {
                    Ticket t = _entity.Tickets.Find(ticket.TicketId);
                    double price = priceTicket.SalePrice;
                    t.PurePrice = (double)price;
                    _entity.Entry(t).State = EntityState.Modified;
                }
                _entity.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public double GetPriceTicket(int theaterId, int chairTypeId)
        {
            double price = 0;
            var priceTicket = from pt in _entity.PriceTickets
                              where pt.ChairTypeId == chairTypeId && pt.TheaterId == theaterId && pt.IsDeleted == false
                              select pt;
            if (priceTicket.FirstOrDefault() != null)
            {
                price = priceTicket.FirstOrDefault().SalePrice;
            }
            return price;
        }

        public int UpdateSelectdTickets(List<Ticket> listNotBookTickets, List<Ticket> listSelectedTickets, int theaterId)
        {
            try
            {
                using (TransactionScope trans = new TransactionScope())
                {
                    try
                    {
                        foreach (var ticket in listNotBookTickets)
                        {
                            ticket.IsDeleted = true;
                            _entity.Entry(ticket).State = EntityState.Modified;
                        }

                        foreach (var ticket in listSelectedTickets)
                        {
                            ticket.IsDeleted = false;
                            int chairTypeId = _chairDao.GetChairByIdWithoutCheckingIsDeleted(ticket.ChairId).ChairTypeId;
                            ticket.PurePrice = GetPriceTicket(theaterId, chairTypeId);
                            _entity.Entry(ticket).State = EntityState.Modified;
                        }
                        int result = _entity.SaveChanges();
                        trans.Complete();
                        return result;
                    }
                    catch (Exception)
                    {
                        trans.Dispose();
                        return 0;
                    }
                }
            }
            catch (Exception ex)
            {
                return 0;
                //throw ex;
            }
        }

    }
}